#include "DualSendRelayHandlerBase.h"

using namespace log4cplus;

Logger DualSendRelayHandlerBase::log=GetLogger(LOG4CPLUS_TEXT("DualSendRelayHandlerBase"));

ITransHandler::ExecuteResultCode DualSendRelayHandlerBase::Execute(ClientContext &client,OVERLAPPED *ovl)
{
	unsigned int clienSequenceNo=client.SequenceNo();
	SOCKET sendSock;
	SOCKET recvSock;
	WSABUF *buf;
	WSABUF *weakRefBuf;
	OVERLAPPED *ovlData;
	GetSendRecvInfo(client,&sendSock,&recvSock,&buf,&weakRefBuf,&ovlData);

	DWORD sendCount=-1;
	DWORD flags;
	BOOL result=::WSAGetOverlappedResult(sendSock,ovlData,&sendCount,true,&flags);
	int errCode=::WSAGetLastError();
	if(result)
	{
		LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]Dual send %d bytes data."),clienSequenceNo,sendCount);
		if(sendCount<weakRefBuf->len)
		{
			LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]Dual send data not complete,resend."),clienSequenceNo);
			weakRefBuf->buf+=sendCount;
			weakRefBuf->len-=sendCount;
			::ZeroMemory(ovlData,sizeof(OVERLAPPED));
			int sendResult=::WSASend(sendSock,weakRefBuf,1,NULL,0,ovlData,NULL);
			errCode=::WSAGetLastError();
			if(sendResult!=0&&errCode!=WSA_IO_PENDING)
			{
				LOG4CPLUS_ERROR_FMT(log,LOG4CPLUS_TEXT("[Client%d]Dual resend data failed,error code:%d."),clienSequenceNo,errCode);
				return ITransHandler::ExecuteFatalError;
			}
		}
		else
		{
			LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]Dual send data complete,rereceive."),clienSequenceNo);
			SetNextHandler(client);
			::ZeroMemory(ovlData,sizeof(OVERLAPPED));
			DWORD flags=0;
			int recvResult=::WSARecv(recvSock,buf,1,NULL,&flags,ovlData,NULL);
			errCode=::WSAGetLastError();
			if(recvResult!=0&&errCode!=WSA_IO_PENDING)
			{
				LOG4CPLUS_ERROR_FMT(log,LOG4CPLUS_TEXT("[Client%d]Dual receive data failed,error code:%d."),clienSequenceNo,errCode);
				return ITransHandler::ExecuteFatalError;
			}
			LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]Begin to rereceive data successed."),clienSequenceNo);
		}
	}
	else
	{
		LOG4CPLUS_ERROR_FMT(log,LOG4CPLUS_TEXT("[Client%d]Dual send data failed,error code:%d."),clienSequenceNo,errCode);
		return ITransHandler::ExecuteFatalError;
	}
	return ITransHandler::ExecuteOK;
}